package user

import (
	"context"
	"fmt"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"gorm.io/gen"
	"gorm.io/gen/field"
	"mall_admin_api/biz/dal"
	handlerCommon "mall_admin_api/biz/handler/common"
	"mall_admin_api/biz/model"
	"mall_admin_api/biz/model/admin_user"
	"mall_admin_api/biz/model/common"
	user2 "mall_admin_api/biz/pack"
)

type User struct {
	commonInfo *handlerCommon.Response
	dao        *dal.InitDAO
}

func NewUser(response *handlerCommon.Response) *User {
	return &User{
		commonInfo: response,
		dao:        dal.NewInitDAO(response.GetBizInfo().ID),
	}
}

func (c *User) FetchList(ctx context.Context, req *admin_user.GetUserListRequest, page, limit int) ([]*admin_user.User, int64, error) {
	var conditions []gen.Condition
	conditions = append(conditions, dal.User.BizID.Eq(c.commonInfo.GetBizInfo().ID))

	list, total, err := c.dao.UserDAO.GetListWithTotal(ctx, &dal.UserListParams{
		Condition: conditions,
		Page:      page,
		Size:      limit,
		Sort:      []field.Expr{dal.User.CreatedAt.Desc()},
	})
	if err != nil {
		hlog.CtxErrorf(ctx, "FetchList err: %v", err)
		return nil, 0, err
	}
	return user2.GetUserList(list), total, nil
}

func (c *User) AddUserPoints(ctx context.Context, req *admin_user.AddUserPointsRequest) error {
	if err := c.dao.Q.Transaction(func(tx *dal.Query) error {
		addPointsFields := []field.AssignExpr{
			dal.User.Points.Add(req.Points),
		}
		condition := []gen.Condition{
			dal.User.BizID.Eq(c.commonInfo.GetBizInfo().ID),
			dal.User.ID.Eq(req.UserID),
		}
		if err := c.dao.UserDAO.UpdateUserWithTx(ctx, tx, condition, addPointsFields); err != nil {
			hlog.CtxErrorf(ctx, "AddUserPoints UpdateUserWithTx err: %v", err)
			return err
		}
		addPointsLog := &model.UserPointsLog{
			BizID:     c.commonInfo.GetBizInfo().ID,
			UserID:    req.UserID,
			Type:      common.UserPointsType_Add,
			Points:    req.Points,
			Remark:    fmt.Sprintf("管理员 %s 添加积分 %d", c.commonInfo.GetAdministratorInfo().Nickname, req.Points),
			AdminID:   c.commonInfo.GetAdministratorInfo().ID,
			CreatedBy: c.commonInfo.GetAdministratorInfo().Nickname,
		}
		if _, err := c.dao.UserPointsLogDAO.CreateUserPointsLogWithTx(ctx, tx, addPointsLog); err != nil {
			hlog.CtxErrorf(ctx, "AddUserPoints CreateUserPointsLogWithTx err: %v", err)
			return err
		}
		return nil
	}); err != nil {
		hlog.CtxErrorf(ctx, "AddUserPoints err: %v", err)
		return err
	}
	return nil
}
